<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<script>
    class NumberTool {
        static format(data, rules) {
            console.log('rulesrulesrulesrules', rules)
            // eslint-disable-next-line no-self-compare
            const condition = (typeof data === 'number' && (data === data)) || typeof data === 'string';
            if (Object.prototype.toString.call(data) === '[object Object]') {
                return NumberTool.objectFormat(data, rules);
            } else if (Array.isArray(data)) {
                data.forEach(item => {
                    NumberTool.objectFormat(item, rules);
                });
                return data; // 返回
            } else if (condition) {
                const {
                    precision,
                    roundingMode
                } = rules[0];
                return NumberTool.simpleDataFormat(data, precision, roundingMode); // 返回 number
            }
            return data;
        }

        /**
         * 对象的格式化，针对数据做处理，不补零
         * @param data
         * @param rules
         */
        static objectFormat(data, rules) {
            const keys = Object.keys(data);
            const ruleFields = rules.map(item => item.field);
            console.log('ruleFields', ruleFields)
            keys.forEach(key => {
                if (ruleFields.indexOf(key) > -1) {
                    const index = rules.findIndex(rule => rule.field === key);
                    const {
                        precision,
                        roundingMode
                    } = rules[index];
                    data[key] = NumberTool.simpleDataFormat(data[key], precision, roundingMode);
                }
            });
            return data;
        }

        /**
         * 基础数据类型的格式化
         * @param data 需要转换的数据
         * @param precision 精度
         * @param roundingMode 取整方式
         */
        static simpleDataFormat(data, precision, roundingMode) {
            let result = NumberTool.getNumber(data);
            if (roundingMode === 'rounding') {
                result = NumberTool.round(result, precision);
            }
            return result;
        }

        /**
         * 根据精度进行补 0，比如：1.8 保留两位是 '1.80'
         * 返回字符串，仅作页面展示
         * @param number
         * @param precision
         */
        static numberToString(number, precision) {
            try {
                number = isNaN(Number(number)) ? 0 : Number(number);
                number = NumberTool.round(number, precision).toString();
                console.log(number);
                const arr = number.split('.');
                const integer = arr[0];
                const decimal = arr[1] || '';

                return decimal.length === precision ? number : `${integer}.${decimal}${'0'.repeat(precision - decimal.length)}`;
            } catch (e) {
                throw new Error(`${e} 传入的数据有误，不是数值！！！`);
            }
        }

        /**
         * 取整方法
         * @param number
         * @param precision
         * @private
         */
        static round(number, precision) {
            return Math.round(Number(+number + 'e' + precision)) / Math.pow(10, precision);
        }

        /**
         * 返回一个有效的数值，不可转为有效数值的转为 0
         * @param number
         * @private
         */
        static getNumber(number) {
            try {
                return Number(number);
            } catch (e) {
                console.warn(`${e} 传入的数据有误，不是数值！！！`);
                return 0;
            }
        }

        /**
         * 把数字根据千分位加都号，并且小数点后补零
         * eg：123456789
         * 123,456,789.00
         * @param number
         * @param separator
         */
        static getStringForThousandths(number, separator) {
            try {
                let result = '';
                let numberStr = String(number);
                let integer = numberStr.split('.')[0]; // 小数点前的整数位
                let remainStr = numberStr.split('.')[1] ? `.${numberStr.split('.')[1]}` : '';
                integer = integer.replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1' + (separator || ','));
                result = `${integer}${remainStr}`;
                return result;
            } catch (e) {
                throw new Error(`${e} 传入的数据有误，不是数值`);
            }
        }

        /**
         * 根据精度进行补 0，并对金额进行千分位加逗号隔开 ，比如：12345.8 保留2位格式化后 '12,345.80'
         * 返回字符串，仅作页面展示
         * @param number
         * @param precision
         * @param separator
         */
        static numberToStringAndThousandths(number, precision, separator) {
            try {
                number = isNaN(Number(number)) ? '0' : Number(number).toString();
                let arr = String(number).split('.');
                let integer = arr[0]
                let decimal = arr[1] || '';
                let zeroPaddingLength = precision - decimal.length;
                // 表示精度位数大于或等于当前小数位数，需要补零
                if (zeroPaddingLength >= 0) {
                    integer = integer.replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1' + (separator || ','));
                    if (precision > 0) {
                        return `${integer}.${decimal}${'0'.repeat(zeroPaddingLength)}`;
                    }
                    return integer;
                }
                let number1 = NumberTool.round(number, precision);
                let arr1 = String(number1).split('.');
                let integer1 = arr1[0].replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1' + (separator || ','));
                let decimal1 = arr1[1] || '';
                if (precision > 0) {
                    if (precision > decimal1.length) {
                        return `${integer1}.${decimal1}${'0'.repeat(precision - decimal1.length)}`;
                    }
                    return `${integer1}.${decimal1}`;
                }
                return integer1;
            } catch (e) {
                throw new Error(`${e} 传入的数据有误，不是数值！！！`);
            }
        }
    }

    let a = 14961.124917;
    console.log(NumberTool.numberToString(a, 4));

</script>
</body>
</html>
